import enum
from PySide6.QtWidgets import QFrame, QTabWidget, QVBoxLayout
from PySide6.QtCore import Qt, QPoint, QRect
from PySide6.QtGui import QMouseEvent, QGuiApplication
#
from util import UiUtil
from view.ChildWindow1 import ChildWindow1
from view.ChildWindow2 import ChildWindow2
from view.TitleBar import TitleBar


class ResizeType(enum.IntFlag):
    """缩放类型"""
    Empty = 0
    Left = 1
    Right = 2
    Top = 3
    Bottom = 4
    LeftTop = 5
    LeftBottom = 6
    RightTop = 7
    RightBottom = 8


class MainWindow(QFrame):
    def __init__(self):
        super().__init__()

        # 设置无边框窗口
        self.setWindowFlags(self.windowFlags() |
                            Qt.WindowType.Window |
                            Qt.WindowType.FramelessWindowHint)
        # 设定组件布局
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        # 添加标题
        title_bar = TitleBar(self)
        title_bar.set_title("PySide6软件界面")
        layout.addWidget(title_bar)

        # 加载ui
        ui = UiUtil.loadUiFile("ui/MainWindow.ui")
        layout.addWidget(ui)

        # 设置主窗口
        self.setMinimumWidth(800)
        self.setMinimumHeight(600)
        self.resize(1024, 768)
        self.center_window()

        self.child_window1 = ChildWindow1()
        self.child_window2 = ChildWindow2()

        # 绑定控件
        if hasattr(ui, 'main_tab'):
            self.main_tab_widget: QTabWidget = ui.main_tab

            self.main_tab_widget.addTab(self.child_window1,
                                        UiUtil.TabName.CHILD_WINDOW1)
            self.main_tab_widget.addTab(self.child_window2,
                                        UiUtil.TabName.CHILD_WINDOW2)
        self.init_mouse_resize()

    def center_window(self):
        """将窗口居中显示在主屏幕上"""
        screen = QGuiApplication.primaryScreen().geometry()
        window_size = self.geometry()
        x = (screen.width() - window_size.width()) // 2
        y = (screen.height() - window_size.height()) // 2
        self.move(x, y)

    def init_mouse_resize(self):
        """初始化鼠标调整大小"""
        self.resize_type = ResizeType.Empty
        self.old_window_rect: QRect = None
        # 设置鼠标跟踪，以便能捕获鼠标移动事件即使无按键按下
        self.setMouseTracking(True)
        # 定义边界宽度，用于判断鼠标是否在边界内
        self.border_width = 3

    def calc_resize_type(self, pos: QPoint):
        """获得缩放类型"""
        rect = self.rect()
        corner_width = self.border_width * 4
        result = ResizeType.Empty
        if pos.x() < corner_width and pos.y() < corner_width:  # 左上角
            result = ResizeType.LeftTop
        elif pos.x() > rect.width() - corner_width and pos.y() > rect.height() - corner_width:  # 右下角
            result = ResizeType.RightBottom
        elif pos.x() > rect.width() - corner_width and pos.y() < corner_width:  # 右上角
            result = ResizeType.RightTop
        elif pos.x() < corner_width and pos.y() > rect.height() - corner_width:  # 左下角
            result = ResizeType.LeftBottom
        elif pos.x() < self.border_width:  # 左边界
            result = ResizeType.Left
        elif pos.x() >= rect.width() - self.border_width:  # 右边界
            result = ResizeType.Right
        elif pos.y() < self.border_width:  # 上边界
            result = ResizeType.Top
        elif pos.y() >= rect.height() - self.border_width:  # 下边界
            result = ResizeType.Bottom
        return result

    def mousePressEvent(self, event: QMouseEvent):
        """鼠标左键按下操作"""
        if event.button() == Qt.MouseButton.LeftButton:
            if self.resize_type != ResizeType.Empty:
                self.old_window_rect = QRect(
                    self.pos().x(), self.pos().y(), self.width(), self.height())
                event.accept()

    def mouseReleaseEvent(self, _: QMouseEvent):
        """鼠标抬起"""
        self.resize_type = ResizeType.Empty
        self.old_window_rect = None
        self.setCursor(Qt.CursorShape.ArrowCursor)

    def mouseMoveEvent(self, event: QMouseEvent):
        """重写鼠标移动"""

        if self.old_window_rect is None:
            # 计算缩放类型
            self.resize_type = self.calc_resize_type(event.pos())

            # 持续响应鼠标变化
            if self.resize_type != ResizeType.Empty:
                self.grabMouse()
            else:
                self.releaseMouse()

            cursor_shape = Qt.CursorShape.ArrowCursor
            if self.resize_type == ResizeType.Left or self.resize_type == ResizeType.Right:
                cursor_shape = Qt.CursorShape.SizeHorCursor
            elif self.resize_type == ResizeType.Top or self.resize_type == ResizeType.Bottom:
                cursor_shape = Qt.CursorShape.SizeVerCursor
            elif self.resize_type == ResizeType.LeftTop or self.resize_type == ResizeType.RightBottom:
                cursor_shape = Qt.CursorShape.SizeFDiagCursor
            elif self.resize_type == ResizeType.LeftBottom or self.resize_type == ResizeType.RightTop:
                cursor_shape = Qt.CursorShape.SizeBDiagCursor

            self.setCursor(cursor_shape)

        # 进行拉伸的响应
        if self.old_window_rect is not None:
            mouse_pos = event.globalPos()
            if self.resize_type == ResizeType.Left:
                width = self.old_window_rect.right() - mouse_pos.x()
                if width > self.minimumWidth():
                    self.setGeometry(
                        mouse_pos.x(), self.old_window_rect.y(), width, self.old_window_rect.height())
            elif self.resize_type == ResizeType.Right:
                width = mouse_pos.x() - self.old_window_rect.x()
                if width > self.minimumWidth():
                    self.setGeometry(
                        self.old_window_rect.x(), self.old_window_rect.y(), width, self.old_window_rect.height())
            elif self.resize_type == ResizeType.Top:
                height = self.old_window_rect.bottom() - mouse_pos.y()
                if height > self.minimumHeight():
                    self.setGeometry(
                        self.old_window_rect.x(), mouse_pos.y(), self.old_window_rect.width(), height)
            elif self.resize_type == ResizeType.Bottom:
                height = mouse_pos.y() - self.old_window_rect.y()
                if height > self.minimumHeight():
                    self.setGeometry(
                        self.old_window_rect.x(), self.old_window_rect.y(), self.old_window_rect.width(), height)
            elif self.resize_type == ResizeType.LeftTop:
                width = self.old_window_rect.right() - mouse_pos.x()
                height = self.old_window_rect.bottom() - mouse_pos.y()
                x = mouse_pos.x()
                y = mouse_pos.y()
                if width <= self.minimumWidth():
                    x = self.old_window_rect.right() - self.minimumWidth()
                if height <= self.minimumHeight():
                    y = self.old_window_rect.bottom() - self.minimumHeight()
                self.setGeometry(x, y, width, height)
            elif self.resize_type == ResizeType.RightBottom:
                width = mouse_pos.x() - self.old_window_rect.x()
                height = mouse_pos.y() - self.old_window_rect.y()
                x = self.old_window_rect.x()
                y = self.old_window_rect.y()
                if width <= self.minimumWidth():
                    width = self.minimumWidth()
                if height <= self.minimumHeight():
                    height = self.minimumHeight()
                self.setGeometry(x, y, width, height)
            elif self.resize_type == ResizeType.LeftBottom:
                width = self.old_window_rect.right() - mouse_pos.x()
                height = mouse_pos.y() - self.old_window_rect.y()
                x = mouse_pos.x()
                y = self.old_window_rect.y()
                if width <= self.minimumWidth():
                    x = self.old_window_rect.right() - self.minimumWidth()
                if height <= self.minimumHeight():
                    height = self.minimumHeight()
                self.setGeometry(x, y, width, height)
            elif self.resize_type == ResizeType.RightTop:
                width = mouse_pos.x() - self.old_window_rect.x()
                height = self.old_window_rect.bottom() - mouse_pos.y()
                x = self.old_window_rect.x()
                y = mouse_pos.y()
                if width <= self.minimumWidth():
                    width = self.minimumWidth()
                if height <= self.minimumHeight():
                    y = self.old_window_rect.bottom() - self.minimumHeight()
                self.setGeometry(x, y, width, height)
